`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/12/18 12:28:28
// Design Name: 
// Module Name: xadc1
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
/*
*************************************XADC顶层使用实例**************************************************
//0、变量定义
    //(1)不更新
wire [11:0] value_temp;
wire [11:0] value_vccint;
wire [11:0] value_vccbram;
    //(2)原始数据
wire adc_clk;
wire [11:0] value_ch1;
wire [11:0] value_ch2;
    //(3)零插数据
wire adc_insert_clk; 
wire [11:0] value_insert_ch1;
wire [11:0] value_insert_ch2;
    //(4)滤波数据
wire adc_filter_clk_ch1; 
wire adc_filter_clk_ch2;
wire [11:0] value_filter_ch1;
wire [11:0] value_filter_ch2;
    //(5)其他
wire [7:0] state;
//1、XADC采集部分
my_xadc u_my_xadc(
    .dclk           (sys_clk),
    .rst_n          (rst_n),
    .ch1_p          (vauxp7),
    .ch1_n          (vauxn7),
    .ch2_p          (vauxp8),
    .ch2_n          (vauxn8),
    
    .value_temp     (value_temp),
    .value_vccint   (value_vccint),
    .value_vccbram  (value_vccbram),

    .adc_clk        (adc_clk),
    .value_ch1      (value_ch1),
    .value_ch2      (value_ch2),

    .adc_insert_clk (adc_insert_clk),
    .value_insert_ch1(value_insert_ch1),
    .value_insert_ch1(value_insert_ch1),

    .adc_filter_clk_ch1(adc_filter_clk_ch1),
    .adc_filter_clk_ch2(adc_filter_clk_ch2),
    .value_filter_ch1  (value_filter_ch1),
    .value_filter_ch2  (value_filter_ch2),

    .state          (state)
);
*/

module my_xadc(
    input dclk,
    input rst_n,
    input ch1_p,ch1_n,
    input ch2_p,ch2_n,
    //不会更新的数据
    output [11:0] value_temp    ,
    output [11:0] value_vccint  ,
    output [11:0] value_vccbram ,
    //原始采集数据
    output reg adc_clk,
    output [11:0] value_ch1     ,
    output [11:0] value_ch2     ,
    //零值内插后的数据
    output reg adc_insert_clk,
    output reg[11:0] value_insert_ch1     ,
    output reg[11:0] value_insert_ch2     ,
    //滤波后的数据
    output wire         adc_filter_clk_ch1,
    output wire         adc_filter_clk_ch2,
    output wire[11:0]   value_filter_ch1     ,
    output wire[11:0]   value_filter_ch2     ,
    //触发输出
    output wire [31:0]  Trigger_cnt,
    output wire [11:0]  Trigger_data,
    output wire         Trigger_clk,
    output wire         Trigger_occur,

    output [7:0] state
);


parameter MULTI_RATE= 4'd4;
parameter read_flag = 8'h0e;
parameter read_zero = 0;



/*******************************************1、XADC进行采集*******************************************/
wire [15:0]  MEASURED_TEMP;
wire [15:0]  MEASURED_VCCINT;
wire [15:0]  MEASURED_VCCBRAM;
wire [15:0]  MEASURED_AUX7;
wire [15:0]  MEASURED_AUX8;
wire [15:0]  MEASURED_AUX12;
wire [15:0]  MEASURED_AUX14;
xadc1 u_XADC_1(
.DCLK               (dclk),
.RESET              (~rst_n),
.VAUXP7             (ch1_p),
.VAUXN7             (ch1_n),
.VAUXP8             (ch2_p),
.VAUXN8             (ch2_n),
// .VAUXP12            (ch2_p),
// .VAUXN12            (ch2_n),
// .VAUXP14            (ch2_p),
// .VAUXN14            (ch2_n),
.MEASURED_TEMP      (MEASURED_TEMP),
.MEASURED_VCCINT    (MEASURED_VCCINT),
.MEASURED_VCCBRAM   (MEASURED_VCCBRAM),
.MEASURED_AUX7      (MEASURED_AUX7),
.MEASURED_AUX8      (MEASURED_AUX8),
.MEASURED_AUX12     (MEASURED_AUX12),
.MEASURED_AUX14     (MEASURED_AUX14),
.state              (state)
);



/*******************************************2、输出数据解析*******************************************/
assign value_ch1        = MEASURED_AUX7[15:4];
assign value_ch2        = MEASURED_AUX8[15:4];
assign value_temp       = MEASURED_TEMP[15:4];
assign value_vccint     = MEASURED_VCCINT[15:4];
assign value_vccbram    = MEASURED_VCCBRAM[15:4];



/*******************************************3、触发一次采集*******************************************/
reg FF0=0;  
reg FF1=0;
wire adc_state_trigger;
wire adc_trigger;
assign adc_state_trigger    =   (state==read_flag);
assign adc_trigger          =   (FF1==0)&&(FF0==1);
always @(posedge dclk or negedge rst_n)begin
    if(!rst_n)begin
        FF0<=0;
        FF1<=0;
    end
    else begin
        FF0<=adc_state_trigger;
        FF1<=FF0;
    end
end

/*******************************************4、adc_clk产生*******************************************/
always @(posedge dclk or negedge rst_n)begin
    if(!rst_n)
        adc_clk<=0;
    else begin
        if(adc_trigger)begin
            adc_clk<=1;
        end
        else 
            adc_clk<=0;
    end
end




/*******************************************5、adc_insert_clk产生*******************************************/
reg [3:0] insert_cnt = 0;
always @(posedge dclk or negedge rst_n)begin
    if(!rst_n)begin
        adc_insert_clk<=0;
        value_insert_ch1<=0;
        value_insert_ch1<=0;
    end
    else begin
        if(adc_trigger)begin//采集一次开始生成时钟
            adc_insert_clk<=1;
            insert_cnt<=MULTI_RATE-1;
            value_insert_ch1<=value_ch1;
            value_insert_ch2<=value_ch2;
        end
        else begin//时钟产生
            if(adc_insert_clk)
                adc_insert_clk<=0;
            else if(insert_cnt!=0)begin//插入零值
                adc_insert_clk<=1;
                insert_cnt<=insert_cnt-1;
                value_insert_ch1<=read_zero;
                value_insert_ch2<=read_zero;
            end 
        end 
    end 
end 

//*******************************************6-1、FIR低通滤波---CH1*******************************************/
wire FIR_dout_rdy_ch1;
wire FIR_dout_vld_ch1;
wire [29:0] FIR_dout_ch1;
wire FIR_din_vld_ch1;
assign FIR_din_vld_ch1 = adc_insert_clk&FIR_dout_rdy_ch1;
fir_compiler_0 fir_ch1 (
  .aclk(dclk),                                  // input wire aclk
  .s_axis_data_tvalid(FIR_din_vld_ch1),          // input wire s_axis_data_tvalid
  .s_axis_data_tready(FIR_dout_rdy_ch1),            // output wire s_axis_data_tready
  .s_axis_data_tdata(value_insert_ch1),         // input wire [15 : 0] s_axis_data_tdata
  .m_axis_data_tvalid(FIR_dout_vld_ch1),            // output wire m_axis_data_tvalid
  .m_axis_data_tdata(FIR_dout_ch1)                  // output wire [31 : 0] m_axis_data_tdata
);
assign adc_filter_clk_ch1   = FIR_dout_vld_ch1;
assign value_filter_ch1     = FIR_dout_ch1[29:18];

//*******************************************6-2、FIR低通滤波---CH2*******************************************/
wire FIR_dout_rdy_ch2;
wire FIR_dout_vld_ch2;
wire [29:0] FIR_dout_ch2;
wire FIR_din_vld;
assign FIR_din_vld_ch2 = adc_insert_clk&FIR_dout_rdy_ch2;
fir_compiler_0 fir_ch2 (
  .aclk(dclk),                                  // input wire aclk
  .s_axis_data_tvalid(FIR_din_vld_ch2),          // input wire s_axis_data_tvalid
  .s_axis_data_tready(FIR_dout_rdy_ch2),            // output wire s_axis_data_tready
  .s_axis_data_tdata(value_insert_ch2),         // input wire [15 : 0] s_axis_data_tdata
  .m_axis_data_tvalid(FIR_dout_vld_ch2),            // output wire m_axis_data_tvalid
  .m_axis_data_tdata(FIR_dout_ch2)                  // output wire [31 : 0] m_axis_data_tdata
);
assign adc_filter_clk_ch2   = FIR_dout_vld_ch2;
assign value_filter_ch2     = FIR_dout_ch2[29:18];

//*******************************************7、触发并输出*******************************************/
wire  [11:0]  adc_data;
assign Trigger_clk  = adc_filter_clk_ch1;
assign adc_data     = value_filter_ch1;
// assign Trigger_clk  = adc_clk;
// assign adc_data     = value_ch1;
trigger_xadc trigger_xadc_1(
.clk            (dclk),
.adc_clk        (Trigger_clk),
.adc_data       (adc_data),
.Trigger_cnt    (Trigger_cnt),
.Trigger_data   (Trigger_data),
.Trigger_occur  (Trigger_occur),
.rst_n          (rst_n)
);

endmodule





module trigger_xadc(
input               clk,
input               adc_clk,
input [11:0]        adc_data,
output reg [31:0]   Trigger_cnt,
output reg [11:0]   Trigger_data,
output reg          Trigger_occur,
input               rst_n
);

parameter  Trigger_level = 12'd1500;
parameter  Trigger_depth = 1024;
/*******************1---触发采集四次********************/
reg [11:0] adc_data_1,adc_data_2,adc_data_3;
always @(posedge adc_clk or negedge rst_n) begin
    if(rst_n==0)begin
        adc_data_1<=0;
        adc_data_2<=0;
        adc_data_3<=0;
    end
    else begin
        adc_data_1<=adc_data;
        adc_data_2<=adc_data_1;
        adc_data_3<=adc_data_2;
    end
end
/*******************2---触发********************/
always @(posedge adc_clk or negedge rst_n)begin
    if(rst_n==0)begin
        Trigger_occur<=0;
        Trigger_cnt<=0;
        Trigger_data<=0;
    end
    else begin
        if(Trigger_cnt==0)begin
            Trigger_data<=0;
            if(  (adc_data>Trigger_level)&&(adc_data_1>Trigger_level)&&(adc_data_2<Trigger_level)&&(adc_data_3<Trigger_level)  )begin
                Trigger_occur<=1'b1;
                Trigger_cnt<=Trigger_depth;
            end
        end
        else begin
            if(Trigger_cnt==1'b1)begin
                Trigger_occur<=1'b0;
            end
            Trigger_cnt<=Trigger_cnt-1'b1;
            Trigger_data<=adc_data;
        end
    end
end


// reg cnt=0;
// always @(posedge clk) cnt <= ~cnt;
// ila_1 u_ila_1 (
// 	.clk   (clk), // input wire clk
// 	.probe0(adc_data), // input wire [11:0]  probe0  
// 	.probe1(Trigger_data), // input wire [11:0]  probe1 
// 	.probe2(Trigger_data), // input wire [11:0]  probe2 
// 	.probe3({adc_clk,1'b0,Trigger_occur,cnt,8'b0})  ,   // input wire [11:0]  probe3
//     .probe4({18'b0,Trigger_cnt[11:0]})
// );

endmodule




module xadc1(
    input DCLK,
    input RESET,
    input VAUXP7,VAUXN7,
    input VAUXP8,VAUXN8,
    input VAUXP12,VAUXN12,
    input VAUXP14,VAUXN14,
    output reg[15:0]MEASURED_TEMP,MEASURED_VCCINT,
    output reg[15:0]MEASURED_VCCBRAM,
    output reg[15:0]MEASURED_AUX7,MEASURED_AUX8,
    output reg[15:0]MEASURED_AUX12,MEASURED_AUX14,
    output[7:0]state
);
    wire[4:0]CHANNEL;
    wire OT;
    wire XADC_EOC;
    wire XADC_EOS;
    wire busy;
    wire [4:0]channel;
    wire drdy;
    reg [6:0] daddr;
    reg [15:0]di_drp;
    wire [15:0]do_drp;
    wire [15:0]aux_channel_p;
    wire [15:0]aux_channel_n;
    reg [1:0]den_reg;
    reg [1:0]dwe_reg;
    reg[7:0]state = init_read;
    reg r_reset = 0;

/************************************状态机参数*************************************/
parameter init_read = 8'h00,
read_waitdrdy = 8'h01,
write_waitdrdy = 8'h03,

read_reg00 = 8'h04,
reg00_waitdrdy = 8'h05,

read_reg01 = 8'h06,
reg01_waitdrdy = 8'h07,

read_reg06 = 8'h08,
reg06_waitdrdy = 8'h09,

//reg17---[7]
read_reg17 = 8'h0a,
reg17_waitdrdy = 8'h0b,
//reg18---[8]
read_reg18 = 8'h0c,
reg18_waitdrdy = 8'h0e,
//reg1c---[12]
read_reg1c = 8'h0f,
reg1c_waitdrdy = 8'h10,
//reg1e---[14]
read_reg1e = 8'h11,
reg1e_waitdrdy = 8'h12;
/********************************XADC采集*************************************/
xadc_wiz_0 xadc1(
    .daddr_in(daddr),
    .dclk_in(DCLK),
    .den_in(den_reg),
    .di_in(di_drp),
    .dwe_in(dwe_reg),

    .reset_in(RESET),

    .vauxp7(VAUXP7),
    .vauxn7(VAUXN7),
    .vauxp8(VAUXP8),
    .vauxn8(VAUXN8),
    // .vauxp12(VAUXP12),
    // .vauxn12(VAUXN12),
    // .vauxp14(VAUXP14),
    // .vauxn14(VAUXN14),

    .busy_out(busy),
    .channel_out(channel),
    .do_out(do_drp),
    .drdy_out(drdy),
    .eoc_out(XADC_EOC),
    .eos_out(XADC_EOS)

    // .vp_in(),
    // .vn_in()
);


//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!以下状态已经该便，请谨慎观察后在判断（改为读完reg18跳回读reg17）
always @ (posedge DCLK)
if(RESET) begin
    state = init_read;
    den_reg = 0;
    dwe_reg = 0;
    di_drp = 16'h0000;
end
else//复位以外的情况，运行状态机
    case(state)
    //1-1---看不懂
    init_read : begin
        daddr = 7'h40;
        den_reg = 2'h2;
        if(busy == 0)state <= read_waitdrdy;
    end
    //1-2---等待输出rdy后，写寄存器，执行完后跳到等待写入完成
    read_waitdrdy:
        if(drdy == 1)begin
        di_drp = do_drp&16'h03_FF;
        daddr = 7'h40;
        den_reg = 2'h2;
        dwe_reg = 2'h2;
        state = write_waitdrdy;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        dwe_reg = {1'b0,dwe_reg[1]};
        state = state;
        end
    //1-3---等待输出rdy后，写入完成，进入读reg00
    write_waitdrdy:
        if(drdy == 1)begin
        state = read_reg00;
        end
        else begin
        den_reg ={1'b0,den_reg[1]};
        dwe_reg ={1'b0,dwe_reg[1]};
        state = state;
        end



    //2-1-1---读reg00
    read_reg00:begin
        daddr = 7'h00;
        den_reg = 2'h2;
        if(XADC_EOS == 1) state <=reg00_waitdrdy;
    end
    //2-1-2---等reg00读完
    reg00_waitdrdy:
        if(drdy==1)begin
        MEASURED_TEMP = do_drp;
        state<=read_reg01;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        state = state;
    end
    

    //2-2-1---读reg01
    read_reg01:begin
        daddr = 7'h01;
        den_reg = 2'h2;
        state <=reg01_waitdrdy;
    end
    //2-2-2---等reg01读完
    reg01_waitdrdy:
        if(drdy==1)begin
        MEASURED_VCCINT = do_drp;
        state<=read_reg06;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        dwe_reg = {1'b0,dwe_reg[1]};
        state = state;
        end



    //2-3-1---读reg06
    read_reg06:begin
        daddr = 7'h06;
        den_reg = 2'h2;
        state <=reg06_waitdrdy;
    end
    //2-3-2---等reg06读完
    reg06_waitdrdy:
        if(drdy==1)begin
        MEASURED_VCCBRAM = do_drp;
        state<=read_reg17;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        dwe_reg = {1'b0,dwe_reg[1]};
        state = state;
        end



    //2-4-1---读reg17
    read_reg17:begin
        daddr = 7'h17;
        den_reg = 2'h2;
        state <=reg17_waitdrdy;
    end
    //2-4-2---等reg17读完
    reg17_waitdrdy:
        if(drdy==1)begin
        MEASURED_AUX7 = do_drp;
        state<=read_reg18;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        dwe_reg = {1'b0,dwe_reg[1]};
        state = state;
        end



    //2-5-1---读reg18
    read_reg18:begin
        daddr = 7'h18;
        den_reg = 2'h2;
        state <=reg18_waitdrdy;
    end
    //2-5-2---等reg18读完
    reg18_waitdrdy:
        if(drdy==1)begin
        MEASURED_AUX8 = do_drp;
        state<=read_reg17;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        dwe_reg = {1'b0,dwe_reg[1]};
        state = state;
        end


    //2-6-1---读reg1c
    read_reg1c:begin
        daddr = 7'h1c;
        den_reg = 2'h2;
        state <=reg1c_waitdrdy;
    end
    //2-6-2---等reg1c读完
    reg1c_waitdrdy:
        if(drdy==1)begin
        MEASURED_AUX12 = do_drp;
        state<=read_reg1e;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        dwe_reg = {1'b0,dwe_reg[1]};
        state = state;
        end
    

    //2-7-1---读reg1c
    read_reg1e:begin
        daddr = 7'h1e;
        den_reg = 2'h2;
        state <=reg1e_waitdrdy;
    end
    //2-7-2---等reg1e读完
    reg1e_waitdrdy:
        if(drdy==1)begin
        MEASURED_AUX14 = do_drp;
        state<=read_reg00;
        end
        else begin
        den_reg = {1'b0,den_reg[1]};
        dwe_reg = {1'b0,dwe_reg[1]};
        state = state;
        end


    endcase
endmodule
